~ chicken-core (master) /manual/Cross development


  1[[tags: manual]]
  2[[toc:]]
  3
  4
  5== Cross Development
  6
  7Since CHICKEN generates C code, it is relatively easy to create
  8programs and libraries for a different architecture than the one the
  9compiler is executing on, a process commonly called ''cross
 10compiling''. Basically you can simply compile Scheme code to C and
 11then invoke your target-specific cross compiler.  To automate the
 12process of invoking the correct C compiler with the correct settings
 13and to simplify the use of extensions, CHICKEN can be built in a
 14special "cross-compilation" mode.
 15
 16Note: in the following text we refer to the "target" as being the
 17platform on which the software is intended to run in the end. We use
 18the term "host" as the system that builds this software. Others use a
 19different nomenclature or switch the meaning of the words.
 20
 21=== Preparations
 22
 23Make sure you have a cross-toolchain in your {{PATH}}. In this
 24example, a Linux system is used to generate binaries for an ARM based
 25embedded system.
 26
 27==== Building the target libraries
 28
 29First you need a version of the runtime system ({{libchicken}}),
 30compiled for the target system. Obtain and unpack a tarball of the
 31CHICKEN sources, or check out the code from the official code
 32repository, then build the libraries and necessary development files:
 33
 34 make ARCH= \
 35     PREFIX=/usr \
 36     PLATFORM=linux \
 37     HOSTSYSTEM=arm-none-linux-gnueabi \
 38     DESTDIR=$HOME/target \
 39     TARGET_FEATURES="-no-feature x86 -feature arm" \
 40     install
 41
 42This will build CHICKEN and install it in {{~/target}}, which we use
 43as a temporary place to store the target files. A few things to note:
 44
 45* {{ARCH}} is empty, since we don't want the build process to detect the architecture (since the target-architecture is likely to be different).  If you know the right string to represent target architecture, you can set {{ARCH}} with that value.  This string is passed to the {{-arch}} compiler and linker option for ios and sometimes conditionally checked in platform-specific makefiles)
 46* {{PREFIX}} gives the prefix ''on the target system'', under which the
 47libraries will finally be installed. In this case it will be {{/usr/lib}}.
 48
 49* {{PLATFORM}} determines the target platform. It must be one of the officially
 50supported platforms CHICKEN runs on. Note that it actually refer to the extension of a dedicated Makefile (`Makefile.linux` in our case).
 51
 52* {{HOSTSYSTEM}} is an identifier for the target system and will be used as
 53the name prefix of the cross C compiler (in this case {{arm-none-linux-gnueabi-gcc}}).
 54If your cross compiler does not follow this convention, pass {{C_COMPILER}} and
 55{{LIBRARIAN}} to the {{make(1)}} invocation, with the names of the C compiler and
 56{{ar(1)}} tool, respectively.
 57
 58* {{DESTDIR}} holds the directory where the compiled library files will temporarily
 59be installed into.
 60
 61* {{TARGET_FEATURES}} contains extra options to be passed to the target-specific
 62Scheme translator; in this case we disable and enable features so that code like
 63the following will do the right thing when cross-compiled:
 64
 65<enscript hightlight=scheme>
 66(cond-expand
 67  (x86 <do this ...>)
 68  ...)
 69</enscript>
 70
 71* If you obtained the sources from a source-code repository and not
 72from an official release tarball, you will need a {{chicken}}
 73executable to compile the Scheme sources of the runtime system. In
 74this case pass yet another variable to the {{make(1)}} invocation:
 75{{CHICKEN=<where the "chicken" executable is>}}.
 76
 77* You can also put all those variables into a file, say {{config.mk}}
 78and run {{make CONFIG=config.mk}}.
 79
 80You should now have these files on {{~/target}}:
 81
 82 |-- bin
 83 |   |-- chicken
 84 |   |-- chicken-bug
 85 |   |-- chicken-install
 86 |   |-- chicken-profile
 87 |   |-- chicken-status
 88 |   |-- chicken-uninstall
 89 |   |-- csc
 90 |   `-- csi
 91 |-- include
 92 |   |-- chicken-config.h
 93 |   `-- chicken.h
 94 |-- lib
 95 |   |-- chicken
 96 |   |   `-- 9
 97 |   |       :
 98 |   |
 99 |   |-- libchicken.a
100 |   |-- libchicken.so -> libchicken.so.9
101 |   `-- libchicken.so.9
102 `-- share
103     |-- chicken
104     |   |-- doc
105     :   ;   :
106     |   |
107     |   `-- setup.defaults
108     `-- man
109         `-- man1
110             :
111
112You should now transfer {{~/target/usr/lib}} to the target system, and place
113its contents in {{/usr/lib}}. You may want to omit the static library {{libchicken.a}} if the target memory is limited.
114
115==== Building the "cross chicken"
116
117Next, we will build another chicken, one that uses the cross C compiler to
118generate target-specific code that uses the target-specific runtime library
119we have just built.
120
121Again, unpack a CHICKEN release tarball or a source tree and run
122{{make(1)}} once again:
123
124 make PLATFORM=linux \
125     PREFIX=$HOME/cross-chicken \
126     TARGETSYSTEM=arm-none-linux-gnueabi \
127     PROGRAM_PREFIX=arm- \
128     TARGET_PREFIX=$HOME/target/usr \
129     TARGET_RUN_PREFIX=/usr \
130     install
131
132* {{PREFIX}} gives the place where the "cross chicken" should be installed
133into. It is recommended not to install into a standard location (like {{/usr/local}}
134or {{$HOME}}) - some files will conflict with a normal CHICKEN installation.
135
136* {{TARGETSYSTEM}} gives the name-prefix of the cross C compiler and other tools (C++ compiler, librarian (ar) and ressource compiler (for windows)).
137
138* {{PROGRAM_PREFIX}} determines the name-prefix of the CHICKEN tools to be created.
139
140* {{TARGET_PREFIX}} specifies where the target-specific files (libraries and
141headers) are located. This is the location where we installed the runtime
142system into.
143
144* {{TARGET_RUN_PREFIX}} holds the PREFIX that will be effective at runtime
145(so {{libchicken.so}} will be found in {{$TARGET_RUN_PREFIX/lib}}).
146
147* Make sure to use the same version of the CHICKEN sources for the target and
148the cross build.
149
150* If you build the cross chicken from repository sources, the same note
151about the {{CHICKEN}} variable applies as given above.
152
153In {{~/cross-chicken}}, you should find the following:
154
155 |-- bin
156 |   |-- arm-chicken
157 |   |-- arm-chicken-install
158 |   |-- arm-chicken-profile
159 |   |-- arm-chicken-status
160 |   |-- arm-chicken-uninstall
161 |   |-- arm-csc
162 |   `-- arm-csi
163 |-- include
164 |   |-- chicken-config.h
165 |   `-- chicken.h
166 |-- lib
167 |   |-- chicken
168 |   |   `-- 9
169 |   |       :
170 |   |
171 |   |-- libchicken.a
172 |   |-- libchicken.so -> libchicken.so.9
173 |   `-- libchicken.so.9
174 `-- share
175     |-- chicken
176     |   |-- doc
177     :   ;   :
178     |   |
179     |   `-- setup.defaults
180     `-- man
181         `-- man1
182             :
183
184To make sure that the right C compiler is used, we ask {{arm-csc}} to show
185the name of the cross C compiler:
186
187  % ~/cross-chicken/bin/arm-csc -cc-name
188  arm-none-linux-gnueabi-gcc
189
190Looks good.
191
192==== Special notes for Linux to Windows cross development
193
194To cross compile from Linux to Windows, you will need to use a Linux build of MingGW-w64 with you can find in most distribution.
195
196As far as the runtime is concerned, the procedure is the same that what have been shown before, using the platform name {{cross-linux-mingw}}.
197
198The procedure to compile the compiler however require some more care:
199* The platform name is {{linux}} because it is where you want your compiler to run
200* You have to set the {{TARGET_LIBRARIES}} as this is different between Linux and Windows:
201  For Linux target, this variable contains {{-ldl -lm}}, while for Windows target it should be {{-lm -lws2_32}}.
202* You have to make sure you are pointing to the right toolchain (see next paragraph).
203
204In order to compile the C sources that Chicken will produce you have to make sure that you provide the right toolchain in both runtime and compiler steps.
205
206In most cases, you want to do that by setting {{HOSTSYSTEM}} when building the runtime and {{TARGETSYSTEM}} when building the compiler to something similar to {{x86_64-w64-mingw32}} (check you distribution binaries). For example:
207
208 # build a CHICKEN runtime for windows
209 > make PREFIX=$HOME/target PLATFORM=cross-linux-mingw HOSTSYSTEM=x86_64-w64-mingw32 install
210 > make confclean
211 # build a CHICKEN cross-compiler that uses the runtime above
212 > make PREFIX=$HOME/cross PROGRAM_PREFIX=mingw- TARGET_PREFIX=$HOME/target PLATFORM=linux TARGETSYSTEM=x86_64-w64-mingw32 TARGET_LIBRARIES="-lm -lws2_32" install
213
214If your distribution does not stick to the {{PREFIX-TOOLNAME}} convention you may want to set some following variables (runtime step/compiler step):
215* {{C_COMPILER}}/{{TARGET_C_COMPILER}}
216* {{CXX_COMPILER}}/{{TARGET_CXX_COMPILER}}
217* {{LIBRARIAN}}/{{TARGET_LIBRARIAN}} for {{ar}}
218* {{RC_COMPILER}}/{{TARGET_RC_COMPILER}} for {{windres}}
219
220You may need this trick to pick {{x86_64-w64-mingw32-gcc-posix}} over {{x86_64-w64-mingw32-gcc-win32}} in Debian for example (those correspond to different thread APIs).
221
222=== Using it
223
224==== Compiling simple programs
225
226  % ~/cross-chicken/bin/arm-csc -v hello.scm
227  /home/felix/cross-chicken/arm-cross-chicken/bin/arm-chicken hello.scm -output-file hello.c -quiet
228  arm-none-linux-gnueabi-gcc hello.c -o hello.o -c -fno-strict-aliasing -DHAVE_CHICKEN_CONFIG_H -g -Wall \
229    -Wno-unused -I /home/felix/cross-chicken/arm-chicken/include
230  rm hello.c
231  arm-none-linux-gnueabi-gcc hello.o -o hello -L/home/felix/cross-chicken/arm-chicken/lib  -Wl,-R/usr/lib -lm \
232    -ldl -lchicken
233  rm hello.o
234
235Is it an ARM binary?
236
237  % file hello
238  hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.16, dynamically linked (uses shared libs), not stripped
239
240Yes, looks good.
241
242==== Compiling extensions
243
244By default, the tools that CHICKEN provides to install, list and uninstall
245extensions will operate on both the host and the target repository.
246So running {{arm-chicken-install}} will compile and install the extension
247for the host system and for the cross-target. To selectively install, uninstall
248or list extensions for either the host or the target system use the
249{{-host}} and {{-target}} options for the tools.
250
251For example, using the mingw-cross-compiler from above, we can create
252a standalone Windows exe file that includes the CHICKEN runtime and all
253egg dependencies.
254
255 # install an egg using the mingw cross compiler above
256 > $HOME/cross/bin/mingw-chicken-install fmt
257 > cat hello.scm
258 (import fmt chicken.platform)
259 (fmt #t "hello world from " (software-type) nl
260      (pretty (features)))
261 # create a standalone exe file with the CHICKEN and fmt statically linked
262 > $HOME/cross/bin/mingw-csc -static hello.scm
263 # hello.exe should now run on Window without any runtime DLL dependencies:
264 > x86_64-w64-mingw32-objdump -p hello.exe | grep "DLL Name"
265    DLL Name: KERNEL32.dll
266    DLL Name: msvcrt.dll
267    DLL Name: USER32.dll
268    DLL Name: WS2_32.dll
269 # or using wine
270 > wine hello.exe
271 hello world from windows
272 (#:windows            #:64bit              #:cross-chicken
273  #:ptables            #:dload              #:little-endian
274  #:x86-64             #:gnu                #:mingw32
275  ...)
276
277
278=== "Target-only" extensions
279
280Sometimes an extension will only be compilable for the target platform
281(for example libraries that use system-dependent features). In this
282case you will have to work around the problem that the host-compiler
283still may need compile-time information from the target-only
284extension, like the import library of modules. One option is to copy
285the import-library source file into the repository of the host compiler:
286
287 # optionally, you can compile the import library:
288 # ~/cross-chicken/bin/arm-csc -O3 -d0 -s target-only-extension.import.scm
289 cp target-only-extension.import.scm ~/cross-chicken/lib/chicken/9
290
291=== Final notes
292
293Cross-development is a very tricky process - it often involves countless
294manual steps and it is very easy to forget an important detail or mix
295up target and host systems. Also, full 100% platform neutrality is
296hard to achieve. CHICKEN tries very hard to make this transparent, but
297at the price of considerable complexity in the code that manages
298extensions.
299
300
301----
302Previous: [[Deployment]]
303
304Next: [[Bugs and limitations]]
Trap